package com.hb.trade.server.project.section.service.raw.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb.core.pojo.enums.FeeTypeEnum;
import com.hb.core.pojo.enums.PayStatusEnum;
import com.hb.core.pojo.enums.SignupStatusEnum;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.notice.entity.Notice;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.dto.SupplyBidSignupDTO;
import com.hb.core.pojo.project.section.entity.SupplyBidSignup;
import com.hb.core.pojo.project.section.mapper.SupplyBidSignupMapper;
import com.hb.trade.server.project.file.service.BidBuyRecordService;
import com.hb.trade.server.project.notice.service.NoticeService;
import com.hb.trade.server.project.order.service.UserOrderService;
import com.hb.trade.server.project.section.manager.SupplyBidSignupManager;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import com.hb.trade.server.project.section.service.raw.SupplyBidSignupService;
import lombok.SneakyThrows;
import org.fzzn.core.model.enums.LogicEnum;
import org.fzzn.core.util.Enums;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 供应商标段报名表 服务实现类
 * </p>
 *
 * @author zhaojk
 * @since 2021-08-30
 */
@Service
public class SupplyBidSignupServiceImpl extends ServiceImpl<SupplyBidSignupMapper, SupplyBidSignup> implements SupplyBidSignupService {

    protected final NoticeService noticeService;
    protected final UserOrderService userOrderService;
    protected final BidSectionService bidSectionService;

    public SupplyBidSignupServiceImpl(NoticeService noticeService, UserOrderService userOrderService, BidSectionService bidSectionService) {
        this.noticeService = noticeService;
        this.userOrderService = userOrderService;
        this.bidSectionService = bidSectionService;
    }

    /**
     * @param supplyBidSignup:
     * @Description: 查询供应商报名列表  跟产品确认 只有公开和需要报名的项目,并且已经发了公告才展示
     * @Author: zhongdl
     * @Date:2021/12/21 16:45
     * @return: {@link PageResult< SupplyBidSignupDTO> }
     **/
    @Override
    public PageResult<SupplyBidSignupDTO> findSupplyBidSignupInfoList(SupplyBidSignupDTO supplyBidSignup) {
        Page<SupplyBidSignupDTO> page = supplyBidSignup.pages();
        // TODO: 2021-11-5 查询集合要筛选是否邀请项目，项目截止报名时间是否已过期，返回参数要带最后一次公告的报名截止时间
        Page<SupplyBidSignupDTO> supplyBidSignupDtoList = baseMapper.pageSupplyBidSignupInfo(page, supplyBidSignup);
        for (SupplyBidSignupDTO supplyBidSignupDto : supplyBidSignupDtoList.getRecords()) {
            Long sectionId = supplyBidSignupDto.getSectionId();
            //查询报名状态
            Integer signupStatus = baseMapper.findSignupFlagStatus(sectionId, supplyBidSignup.getOrgId(), null);
            supplyBidSignupDto.setSignupStatus(signupStatus);
            supplyBidSignupDto.setSignupStatusName(Enums.nameOf(SignupStatusEnum.class, supplyBidSignupDto.getSignupStatus()));
            //查询公告名称
            Notice notice = noticeService.lastNoticeBySectionId(sectionId);
            supplyBidSignupDto.setNoticeTitle(notice.getNoticeTitle());
            supplyBidSignupDto.setNoticeId(notice.getId());

        }
        return PageResult.get(page);
    }

    /**
     * 根据项目id查询标段的报名信息
     *
     * @param projectId 项目id
     * @return
     */
    @Override
    public List<SupplyBidSignupDTO> findBidSectionSignUpInfo(Long projectId) {
        return baseMapper.findBidSectionSignUpInfo(projectId);
    }

    /**
     * 查询我的项目信息
     *
     * @param supplyBidSignup
     * @return
     */
    @Override
    public Page<SupplyBidSignupDTO> findMyProjectList(SupplyBidSignupDTO supplyBidSignup) {
        // TODO: 2021-11-5  查询我的项目，是否应该也带上接受了邀请的项目？？？还是说接受了邀请后，会在报名表中新增数据？
//        if (StrUtil.isEmpty(supplyBidSignup.getSupplyId())){
//            supplyBidSignup.setSupplyId(userProvider.get().getOrganizeId());
//        }
        Page<SupplyBidSignupDTO> page = supplyBidSignup.pages();
        Page<SupplyBidSignupDTO> supplyBidSignupDtoList = baseMapper.findMyProjectList(page, supplyBidSignup);
        BidBuyRecordService bidBuyRecordService = SpringUtil.getBean(BidBuyRecordService.class);

        //查询最后一次发布公告的时间
        for (SupplyBidSignupDTO supplyBidSignupDto : supplyBidSignupDtoList.getRecords()) {
            Long sectionId = supplyBidSignupDto.getSectionId();

//            supplyBidSignupDto.setSectionStatusName(dictionarydataService.getDicName(supplyBidSignupDto.getSectionStatus()));
            //查询最后一次公告公告
            Notice notice = noticeService.lastNoticeBySectionId(sectionId);
            supplyBidSignupDto.setNoticeTitle(notice.getNoticeTitle());
//            supplyBidSignupDto.setBidOpeningTime(notice.getBidOpeningTime());
            supplyBidSignupDto.setBidWayName(Enums.nameOf(BidWayEnum.class, supplyBidSignupDto.getBidWay()));

            // 标书售价
            BigDecimal documentSalePrice = userOrderService.getPrice(sectionId, FeeTypeEnum.DOC_BOOK);
            if (NumberUtil.equals(documentSalePrice, BigDecimal.ZERO)) {
                supplyBidSignupDto.setPayStatus(PayStatusEnum.PAY_SUCCESS.getCode());
            } else {
                //查询报名状态
                Boolean flag = bidBuyRecordService.payFlag(sectionId, supplyBidSignupDto.getBidderId(), supplyBidSignupDto.getOrgId());
                supplyBidSignupDto.setPayStatus(flag ? LogicEnum.YES.getCode() : LogicEnum.NO.getCode());
            }
        }
        return supplyBidSignupDtoList;
    }

    /**
     * 根据标段id查询当前标段下的报名数量
     *
     * @param sectionId
     * @return
     */
    @Override
    public Integer findSectionSignUpCount(Long sectionId) {
        return baseMapper.findSectionSignUpCount(sectionId);
    }

    /**
     * @param supplyBidSignup:
     * @Description: 招标人查询标段下的所有报名信息
     * @Author: zhongdl
     * @Date:2021/12/21 14:38
     * @return: {@link List< SupplyBidSignupDTO> }
     **/
    @Override
    public List<SupplyBidSignupDTO> getSectionSigupList(SupplyBidSignupDTO supplyBidSignup) {
        QueryWrapper<SupplyBidSignup> wrapper = SupplyBidSignupManager.fillCondition(supplyBidSignup);
        List<SupplyBidSignup> supplySigupList = baseMapper.selectList(wrapper);
        //List<SupplyBidSignup> 装换为 List<SupplyBidSignupDto>

        return SupplyBidSignupManager.changeSupplyBidSignupDTO(supplySigupList);
    }

    /**
     * @param supplyBidSignup:
     * @Description: 招标人查询标段下的所有报名信息(带分页)
     * @Author: zhongdl
     * @Date:2021/12/21 14:38
     * @return: {@link List< SupplyBidSignupDTO> }
     **/
    @Override
    public PageResult<SupplyBidSignupDTO> pageSectionSignup(SupplyBidSignupDTO supplyBidSignup) {
        Page<SupplyBidSignup> pages = supplyBidSignup.pages();
        QueryWrapper<SupplyBidSignup> wrapper = SupplyBidSignupManager.fillCondition(supplyBidSignup);
        page(pages, wrapper);
        //List<SupplyBidSignup> 装换为 List<SupplyBidSignupDto>
        List<SupplyBidSignupDTO> supplyBidSignupDTOS = SupplyBidSignupManager.changeSupplyBidSignupDTO(pages.getRecords());
        //转换PageResult泛型
        PageResult<SupplyBidSignupDTO> supplyBidSignupDTOPageResult = PageResult.get(pages).transferTo(SupplyBidSignupDTO.class);
        supplyBidSignupDTOPageResult.setRecords(supplyBidSignupDTOS);
        return supplyBidSignupDTOPageResult;
    }

    @Override
    @SneakyThrows
    public SupplyBidSignupDTO getSupplySignupInfo(Long id) {
        //根据标段Id与供应商Id查询报名详细信息
        SupplyBidSignup supplyBidSignup = getById(id);
        if (null == supplyBidSignup) {
            return new SupplyBidSignupDTO();
        }
        //将父类转换成子类DTO
        SupplyBidSignupDTO supplyBidSignupDto = supplyBidSignup.to(SupplyBidSignupDTO.class);
        supplyBidSignupDto.setSignupStatusName(Enums.nameOf(SignupStatusEnum.class, supplyBidSignupDto.getSignupStatus()));
        supplyBidSignupDto.setBondFlagName(Enums.nameOf(LogicEnum.class, supplyBidSignupDto.getBondFlag()));
        return supplyBidSignupDto;
    }

    /**
     * 投标人报名审核
     *
     * @param supplyBidSignup
     * @return
     */
    @Override
    public Boolean signupExamine(SupplyBidSignup supplyBidSignup) {
        if (null == supplyBidSignup.getId()) {
            return false;
        }
        supplyBidSignup.setProcessingTime(LocalDateTime.now());
        int row = baseMapper.updateById(supplyBidSignup);
        return row == 1;
    }

    /**
     * @param signupStatusEnum: 1 已报名 2 未报名/已保存 3 报名未通过 4 报名中
     * @param sectionId:        标段id
     * @Description: 根据标段id查询各个状态的数量
     * @Author: zhongdl
     * @Date:2021/12/21 10:32
     * @return: {@link Integer }
     **/
    @Override
    public Long findSignupStatusCount(SignupStatusEnum signupStatusEnum, Long sectionId) {
        QueryWrapper<SupplyBidSignup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("section_id", sectionId).eq("signup_status", signupStatusEnum.getCode());

        return this.count(queryWrapper);
    }


    @Override
    public SupplyBidSignupDTO getSignupCountBySectionId(Long sectionId) {
        if (null == sectionId) {
            return new SupplyBidSignupDTO();
        }
        SupplyBidSignupDTO supplyBidSignup = new SupplyBidSignupDTO();
        //查询待确认的数量
        Long beConfirmedCount = findSignupStatusCount(SignupStatusEnum.REG_PROGRESS, sectionId);
        //查询不通过的数量
        Long failCount = findSignupStatusCount(SignupStatusEnum.REG_FAILED, sectionId);
        //查询已通过的数量
        Long adoptCount = findSignupStatusCount(SignupStatusEnum.REGISTERED, sectionId);
        supplyBidSignup.setBeConfirmedCount(beConfirmedCount);
        supplyBidSignup.setFailCount(failCount);
        supplyBidSignup.setAdoptCount(adoptCount);
        supplyBidSignup.setTotalCount(beConfirmedCount + failCount + adoptCount);
        //查询报名时间
        BidSectionDTO bidSectionDTO = bidSectionService.findBidAndProjectBySectionId(sectionId);
        bidSectionDTO.to(supplyBidSignup);
        return supplyBidSignup;
    }

    /**
     * @param sectionId:
     * @Description: 根据标段id 更新审核通过的报名信息  更改为报名中的状态
     * @Author: zhongdl
     * @Date:2022/1/13 17:16
     * @return: {@link boolean }
     **/
    @Override
    public boolean updateExamineStatus(Long sectionId) {
        UpdateWrapper<SupplyBidSignup> wrapper = new UpdateWrapper<>();
        wrapper.set("signup_status", SignupStatusEnum.REG_PROGRESS.getCode())
                .eq("section_id", sectionId)
                .eq("signup_status", SignupStatusEnum.REGISTERED.getCode());
        return update(wrapper);
    }

    /**
     * @param orgId:
     * @param bidderId:
     * @param sectionId:
     * @Description: 查看当前企业的标段报名信息
     * @Author: zhongdl
     * @Date:2022/1/28 9:53
     * @Updata :  fengbin 新增查看当前企业的标段报名信息（无投标人id的情况）
     * @return: {@link SupplyBidSignup }
     **/
    @Override
    public SupplyBidSignup getOrgSupplyBidSignupInfo(Long orgId, Long bidderId, Long sectionId) {
        QueryWrapper<SupplyBidSignup> wrapper = SupplyBidSignup.wrapper();
        wrapper.eq("org_id", orgId);
        if (!ObjectUtils.isEmpty(bidderId)) {
            wrapper.eq("bidder_id", bidderId);
        }
        wrapper.eq("section_id", sectionId).last("limit 1");
        return getOne(wrapper);
    }

    /**
     * 导出投标人报名列表信息
     *
     * @param supplyBidSignup
     * @return
     * @author zhaojk
     */
    @Override
    public List<JSONObject> listSectionSignup(SupplyBidSignupDTO supplyBidSignup) {
        return baseMapper.listSectionSignup(supplyBidSignup);
    }

    /**
     * 修改报名表中的投标文件递交状态
     *
     * @param sectionId 标段ID
     * @param orgId     投标用户所在企业ID
     * @param bidderId  投标用户ID
     * @return
     */
    @Override
    public boolean updateTenderFileStatus(Long sectionId, Long orgId, Long bidderId, int status) {
        if (sectionId == null || orgId == null || bidderId == null) {
            return false;
        }
        QueryWrapper<SupplyBidSignup> wrapper = SupplyBidSignup.wrapper();
        wrapper.eq("section_id", sectionId);
        wrapper.eq("org_id", orgId);
        wrapper.eq("bidder_id", bidderId);

        SupplyBidSignup one = getOne(wrapper);
        if (one == null){
            return false;
        }
        one.setSubmitFlag(status);
        return updateById(one);
    }
}
